﻿using Codemonk.Common.Caching;
using Codemonk.Common.Configuring;
using System;
namespace Codemonk.Common.Data
{
    public sealed class DbAccessorFactory : IDbAccessorFactory
    {
        private static readonly DbAccessorBuilder builder;

        static DbAccessorFactory()
        {
            builder = new DbAccessorBuilder { Reader = new AssemblyConfigReader { EnableMonitoring = true } };
        }

        private class DbAccessorBuilder : Configurable
        {
            private readonly ICacheCollection<string, Tuple<string, string>> cache = new DictionaryCache<string, Tuple<string, string>>();

            private bool initializated = false;

            public override void Initialization()
            {
                try
                {
                    ICacheCollection<string, Tuple<string, string>> tmpCache = new DictionaryCache<string, Tuple<string, string>>();
                    var connectionstrings = Reader.ReadTriple("/codemonk/connectionstrings//connectionstring", "@name", "@value", "@providerinvariantname");
                    if (connectionstrings != null)
                    {
                        foreach (var connectionstring in connectionstrings)
                            tmpCache.Set(connectionstring.Item1, new Tuple<string, string>(connectionstring.Item2, connectionstring.Item3));
                        cache.Clear();
                        cache.Set(tmpCache);
                    }
                }
                catch { }
            }

            public Tuple<string, string> GetConfig(string name)
            {
                if (!initializated) { initializated = true; Initialization(); }
                Tuple<string, string> config;
                if (cache.TryGet(name, out config)) return config;
                return null;
            }
        }

        private static readonly object sync = new object();

        public IDbAccessor Get(string name = null)
        {
            var config = builder.GetConfig(name);
            if (config == null) return null;
            return new DbAccessor
            {
                ConnectionString = config.Item1,
                ProviderInvariantName = config.Item2
            };
        }
    }
}
